home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_078 / mandelvroom / contour.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  32KB  |  1,116 lines

  1. /***************************************************************************
  2.  *
  3.  *                 MandelVroom Contour Editing Window
  4.  *
  5.  *                         Kevin L. Clague
  6.  *
  7.  *                        Copyright (C) 1987
  8.  *
  9.  **************************************************************************/
  10.  
  11. #include "mand.h"
  12.  
  13. extern struct Screen *screen;
  14. extern struct RastPort *rp;
  15. extern struct Window *MandWind;
  16.  
  17. extern SHORT MouseX,MouseY;
  18.  
  19. extern SHORT MaxCount;
  20.  
  21. extern struct Menu Menu[];
  22.  
  23. extern USHORT CmdMode;
  24.  
  25. extern SHORT Zoom;
  26.  
  27. USHORT CurContour;
  28.  
  29. struct Window *ContWind;
  30.  
  31. BYTE ContTitle[80];
  32.  
  33. struct NewWindow NewCont = {
  34.    0,200-80,                 /* start position           */
  35.    320,200,                  /* width, height            */
  36.    (UBYTE) 0, (UBYTE) 1,     /* detail pen, block pen    */
  37.                              /* IDCMP flags */
  38.    MENUPICK | GADGETDOWN | GADGETUP | REQCLEAR | CLOSEWINDOW,
  39.                              /* MandWind flags */
  40.    WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH | NOCAREREFRESH,
  41.    (struct Gadget *) NULL,   /* first gadget             */
  42.    (struct Image *) NULL,    /* user checkmark           */
  43.    (UBYTE *) NULL,           /* window title             */
  44.    (struct Screen *) NULL,   /* pointer to screen        */
  45.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  46.    80,80,320,200,            /* sizing                   */
  47.    CUSTOMSCREEN              /* type of screen           */
  48.    };
  49.  
  50. SHORT Ceiling = 1023;
  51.  
  52. extern SHORT *CountBase;
  53. extern SHORT CountX, CountY;
  54.  
  55. SHORT  Contours[NUMCONTS] = {
  56.       1023,128,64, 32, 27, 26, 25, 24,
  57.       23, 22, 21, 20, 19, 18, 17, 16,
  58.       15, 14, 13, 12, 11, 10, 9,  8,
  59.        7, 6,  5,  4,  3,  2,  1,  0
  60.       };
  61. SHORT *ContourBase = Contours;
  62. SHORT  NumContours = NUMCONTS;
  63.  
  64. UBYTE  Colors[NUMCONTS] = {
  65.       0,  1,  2,  3,  4,  5,  6,  7,
  66.       8,  9,  10, 11, 12, 13, 14, 15,
  67.       16, 17, 18, 19, 20, 21, 22, 23,
  68.       24, 25, 26, 27, 28, 29, 30, 31
  69.       };
  70. UBYTE *ColorBase = Colors;
  71.  
  72. struct Gadget *ContGadget[NUMCONTS];
  73. struct Gadget *SelGadget[NUMCONTS];
  74.  
  75.  
  76. /*
  77.  * Figure out what to do for this contour gadget
  78.  */
  79. DoContourDown(gadget)
  80.   struct Gadget *gadget;
  81. {
  82.   USHORT  ContNum;
  83.   USHORT  Type;
  84.  
  85.   extern LONG NavTop, NavBot, NavLeft, NavRight;
  86.  
  87.   ContNum = gadget->GadgetID & NUMMASK;
  88.  
  89.   switch (Type = gadget->GadgetID >> TYPEBITS & TYPEMASK) {
  90.     case CONTCNTLS:
  91.          switch (gadget->GadgetID) {
  92.            case CONTRECOL:
  93.                 ReColor();
  94.                 DisplayBeep(screen);
  95.  
  96.                 if (Zoom) {
  97.                   DrawBox(NavLeft, NavTop, NavRight, NavBot );
  98.                   DrawExtras(NavLeft, NavTop, NavRight, NavBot );
  99.                 }
  100.                 SetNormPointer();
  101.                 break;
  102.  
  103.            case CONTSMTH:
  104.                 SetToPointer();
  105.                 CmdMode = SMOOTH;
  106.                 break;
  107.          }
  108.          break;
  109.  
  110.     case CONTSELS:
  111.          if (CmdMode == SMOOTH) {
  112.            SetNormPointer();
  113.            SmoothContours(CurContour, ContNum);
  114.  
  115.          } else {
  116.            SetNormPointer();
  117.            CmdMode = IMPLIEDSET;
  118.          }
  119.          break;
  120.  
  121.     case CONTDOWNS:
  122.          if (*(ContourBase + ContNum) > 0) {
  123.            *(ContourBase + ContNum) -= 1;
  124.          }
  125.          ReString(ContNum);
  126.          SetNormPointer();
  127.          break;
  128.  
  129.     case CONTUPS:
  130.          if (*(ContourBase + ContNum) < MaxCount) {
  131.            *(ContourBase + ContNum) += 1;
  132.          }
  133.          ReString(ContNum);
  134.          SetNormPointer();
  135.          break;
  136.   }
  137.  
  138.   if ( Type != CONTCNTLS ) {
  139.     DrawContBox(CurContour, 0);
  140.     DrawContBox(ContNum, 1);
  141.  
  142.     CurContour = ContNum;
  143.     SetContTitle(ContNum);
  144.   }
  145. }
  146.  
  147. /*
  148.  * Figure out what to do for this contour gadget
  149.  */
  150. DoContourUp(gadget)
  151.   struct Gadget *gadget;
  152. {
  153.   USHORT  ContNum;
  154.   struct  PropInfo *PropInfo;
  155.   ULONG   VertPot;
  156.   char    msg[80];
  157.  
  158.   ContNum = gadget->GadgetID & NUMMASK;
  159.   SetNormPointer();
  160.  
  161.   PropInfo = (struct PropInfo *) gadget->SpecialInfo;
  162.  
  163.   VertPot = PropInfo->VertPot + 1;
  164.  
  165.   switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
  166.     case CONTCNTLS:
  167.          Ceiling = ((LONG) MaxCount - ( VertPot * MaxCount  >> 16));
  168.          ModAll();
  169.          break;
  170.  
  171.     case CONTPOTS:
  172.          if (ContourBase[ContNum] < Ceiling) {
  173.            ContourBase[ContNum] =
  174.                ( (LONG) Ceiling ) - (VertPot * Ceiling >> 16);
  175.          } else {
  176.            PropInfo->VertPot = 0;
  177.            RefreshGList(gadget,ContWind,NULL,1);
  178.          }
  179.  
  180.          DrawContBox(CurContour, 0);
  181.          DrawContBox(ContNum, 1);
  182.  
  183.          CurContour = ContNum;
  184.          SetContTitle(ContNum);
  185.  
  186.          break;
  187.   }
  188. }
  189.  
  190. /*
  191.  * Set the contour window's new title
  192.  */
  193. SetContTitle(ContNum)
  194.   int ContNum;
  195. {
  196.   SHORT Low, High;
  197.  
  198.   char *fmt1 = "Contour: %d Alt: %d-%d Pen: %d";
  199.   char *fmt2 = "Contour: %d Alt: %d Pen: %d";
  200.  
  201.   High = ContourBase[ContNum];
  202.  
  203.   if (ContNum != 0) {
  204.     Low  = ContourBase[ContNum-1];
  205.  
  206.     if (Low == High || Low - High == 1) {
  207.       sprintf(ContTitle, fmt2, ContNum, High, ColorBase[ContNum]);
  208.     } else {
  209.       sprintf(ContTitle, fmt1, ContNum, Low - 1, High, ColorBase[ContNum]);
  210.     }
  211.   } else {
  212.  
  213.     sprintf(ContTitle, fmt2, ContNum, MaxCount, High, ColorBase[ContNum]);
  214.   }
  215.   SetWindowTitles(ContWind, ContTitle, NULL);
  216. }
  217.  
  218. /*
  219.  * Set Potentiometer knob's pen
  220.  */
  221. DrawContBox(Contour, pen)
  222.   ULONG Contour;
  223.   int pen;
  224. {
  225.   LONG Left, Right, Top, Bottom;
  226.   LONG Scaled4;
  227.   struct RastPort *rp = ContWind->RPort;
  228.  
  229.   extern USHORT XScale, YScale;
  230.  
  231.   Scaled4 = 4 << XScale;
  232.  
  233.   Left = (6 << XScale) * Contour + Scaled4 - 1;
  234.   Right = Left + Scaled4 + 1;
  235.  
  236.   Top = (12 << YScale) - 1;
  237.   Bottom = Top + (4 << YScale) + 1;
  238.  
  239.   SetDrMd(rp, (LONG) JAM1);
  240.   SetAPen(rp, (LONG) pen);
  241.   /*
  242.    * Draw the new box
  243.    */
  244.   Move(rp, Left,  Top   );
  245.   Draw(rp, Right, Top   );
  246.   Draw(rp, Right, Bottom);
  247.   Draw(rp, Left,  Bottom);
  248.   Draw(rp, Left,  Top+1 );
  249.  
  250. } /* DrawContBox */
  251.  
  252. /*
  253.  *  There was a window pick. Do what we need to do to service it
  254.  */
  255. DoWindowPick(MouseX,MouseY)
  256.   SHORT MouseX,MouseY;
  257. {
  258.   USHORT Height;
  259.  
  260.   if (MouseX >= LEFTMARG && MouseX <= MandWind->Width-RIGHTMARG &&
  261.       MouseY >= TOPMARG  && MouseY <= MandWind->Height-BOTMARG) {
  262.  
  263.     if (CmdMode == IMPLIEDSET) {
  264.       Height = *(CountBase + (MouseY-TOPMARG)*CountX + MouseX - LEFTMARG);
  265.       *(ContourBase + CurContour) = Height;
  266.       ReString(CurContour);
  267.     }
  268.   }
  269. }
  270.  
  271. /*
  272.  *  Smooth the heights over a subrange of contours
  273.  */
  274. SmoothContours(First,Second)
  275.   USHORT First, Second;
  276. {
  277.   USHORT Temp;
  278.   float Diff,Start;
  279.  
  280.   if (Second-First != 0) {
  281.  
  282.     if (Second < First) {
  283.       Temp = First;
  284.       First = Second;
  285.       Second = Temp;
  286.     }
  287.  
  288.     Start = (float) ContourBase[First];
  289.     Diff = (((float) ContourBase[Second]) - Start)/((float)(Second-First));
  290.  
  291.     if (Diff > -1.0) {
  292.       Diff = -1.0;
  293.     }
  294.  
  295.     for ( ; First < Second && Start > 0; First++)
  296.       ContourBase[First + 1] = (SHORT) (Start += Diff);
  297.  
  298.     if (Start == 0) {
  299.       for ( ; First < NumContours; First++) {
  300.         ContourBase[First] = 0;
  301.       }
  302.     }
  303.  
  304.     ModAll();
  305.   }
  306. } /* SmoothContours */
  307.  
  308. /*
  309.  * ReColor the Mandelbrot image
  310.  */
  311. ReColor() {
  312.   SHORT *CountPtr = CountBase;
  313.   SHORT  Mask,Width;
  314.   LONG   Mod,CMod;
  315.   SHORT  LF,LP,RF,RP,D[6];
  316.   SHORT  i,j,k,l, Depth;
  317.   LONG   Sx,TL;
  318.   SHORT *Planes[6];
  319.  
  320.   UBYTE *ColorPtr;
  321.   UBYTE *ColorSave,t;
  322.   UBYTE  T[1030];
  323.  
  324.   Depth = screen->BitMap.Depth;
  325.  
  326.   if (CountPtr == NULL) {
  327.     DispErrMsg("No counts to recolor",0);
  328.     return(0);
  329.   }
  330.   if (screen->Width < CountX+LEFTMARG+RIGHTMARG ||
  331.       screen->Height < CountY+TOPMARG+BOTMARG) {
  332.     DispErrMsg("Picture too big for screen.",0);
  333.     return(0);
  334.   }
  335.  
  336.   if (MandWind->Width  != CountX+LEFTMARG+RIGHTMARG ||
  337.       MandWind->Height != CountY+TOPMARG+BOTMARG)
  338.       SizeWindow(MandWind,CountX+LEFTMARG+RIGHTMARG-MandWind->Width,
  339.                           CountY+TOPMARG+BOTMARG-MandWind->Height);
  340.  
  341.   WindowToFront(MandWind);
  342.  
  343.   SetAPen( rp, 0L );
  344.   RectFill( rp, LEFTMARG, TOPMARG, LEFTMARG + CountX, TOPMARG + CountY );
  345.  
  346.   if ( Depth < 4 || Depth == 6) {
  347.     ReColorSlow();
  348.     return(0);
  349.   }
  350.  
  351.   /* try to get enough memory to recolor the picture fast. */
  352.   ColorPtr = ColorSave = (UBYTE *) AllocMem((LONG) CountX * CountY, 0L);
  353.   if (ColorPtr == (UBYTE *) NULL) {
  354.     ReColorSlow();
  355.     return(0);
  356.   }
  357.  
  358.   /* So recolor it now that you have the memory */
  359.   for (i = 0,j = 1029; i < NUMCONTS; i++)
  360.     for (; j >= ContourBase[i] && j; )
  361.       T[j--] = ColorBase[i];
  362.   while (j >= 0) T[j--] = 0;
  363.  
  364.   ;
  365. #ifdef SLOW1
  366.   for (Sx = CountX*CountY; Sx-- >= 0; )  *(ColorPtr++) = T[*(CountPtr++)];
  367. #else
  368. #asm
  369. CountPtr  equ -4
  370. ColorBase equ -82
  371. T         equ -1117
  372.    move.w   _CountX,d1
  373.    muls.w   _CountY,d1
  374.    sub.l    #1,d1
  375.    move.l   CountPtr(a5),a0
  376.    lea      T(a5),a1
  377.    move.l   ColorBase(a5),a6
  378. ColorLoop
  379.    move.w   (a0)+,d0
  380.    move.b   (a1,d0.w),(a6)+
  381.    sub.l    #1,d1
  382.    bge      ColorLoop
  383. #endasm
  384. #endif
  385.  
  386.   ClearMenuStrip(MandWind);
  387.  
  388.   if (Depth == 4) {
  389.     ReColor4(ColorSave);
  390.   } else
  391.   if (Depth == 5) {
  392.     ReColor5(ColorSave);
  393.   }
  394.   SetMenuStrip(MandWind, Menu);
  395.  
  396.   FreeMem(ColorSave,CountX*CountY);
  397. } /* ReColor */
  398.  
  399. /*
  400.  * Assembly code to recolor 4 bit planes
  401.  */
  402. ReColor4(ColorSave)
  403.   UBYTE *ColorSave;
  404. {
  405.   SHORT  Mask,Width;
  406.   LONG   Mod,CMod;
  407.   SHORT  LF,LP,RF,RP;
  408.   SHORT  i,j,k,l;
  409.   LONG   Sx,TL;
  410.   UBYTE  *ColorPtr;
  411.  
  412.   struct BitMap *BitMap = MandWind->RPort->BitMap;
  413.  
  414. #asm
  415. SaveReg  reg a0-a6/d0-d7
  416. Plane0   equ 8
  417. Plane1   equ Plane0+4
  418. Plane2   equ Plane0+8
  419. Plane3   equ Plane0+12
  420. Plane4   equ Plane0+16
  421. Plane5   equ Plane0+20
  422.  
  423. BitMap    equ -44
  424. ColorPtr  equ -40
  425. TL        equ -36
  426. Sx        equ -32
  427. l         equ -28
  428. k         equ -26
  429. j         equ -24
  430. i         equ -22
  431. RP        equ -20
  432. RF        equ -18
  433. LP        equ -16
  434. LF        equ -14
  435. CMod      equ -12
  436. Mod       equ -8
  437. Width     equ -4
  438. Mask      equ -2
  439. ColorSave equ 8
  440. #endasm
  441.  
  442.   ColorPtr = ColorSave;
  443.   Sx = screen->Width >> 4;
  444.   LF = MandWind->LeftEdge + 17 & 0xfff0;
  445.   LP = MandWind->LeftEdge + LEFTMARG;
  446.   CMod = CountX - (LF-LP);
  447.   Mod = Sx - 1;
  448.   TL = Sx * (MandWind->TopEdge + TOPMARG) + (LP >> 4);
  449.   Width = LF-LP;
  450.   Mask = 0xffff << Width;
  451.  
  452. #asm
  453.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  454.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  455.   move.w  _CountY,i(a1)
  456.   move.l  BitMap(a1),a0
  457.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  458.   asl.l   #1,d0                  ; and make it a 'word' offset
  459.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  460.   adda.l  d0,a2                  ; add in window top-left offset.
  461.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  462.   adda.l  d0,a3
  463.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  464.   adda.l  d0,a4
  465.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  466.   adda.l  d0,a5
  467.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  468.   move.l  #1,d1                  ;/* for each row */
  469. ;                                for (i = CountY; i; i--) {
  470. Y0Loop4                            ; /* for each pixel in column */
  471.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  472.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  473.   eor.w   d3,d3
  474.   eor.w   d4,d4
  475.   eor.w   d5,d5
  476. B0Loop4
  477.   move.b  (a0)+,d0               ;    d0 = *(ColorPtr++);
  478.   asr.b   d1,d0                  ;    get low order bit from d0
  479.   addx.w  d2,d2                  ;    put it in bit plane 0 data
  480.   asr.b   d1,d0                  ;    same for bit plane 1
  481.   addx.w  d3,d3
  482.   asr.b   d1,d0                  ;    same for bit plane 2
  483.   addx.w  d4,d4
  484.   asr.b   d1,d0                  ;    same for bit plane 3
  485.   addx.w  d5,d5
  486.   sub.w   d1,d7                  ;    same for bit plane 5
  487.   bgt     B0Loop4                ;  } /* did each bit in bit plane word */
  488.   move.w  Mask(a1),d0            ;  Turn off all the new bits in planes
  489.   and.w   d0,(a2)
  490.   and.w   d0,(a3)
  491.   and.w   d0,(a4)
  492.   and.w   d0,(a5)
  493.   or.w    d2,(a2)+               ;  Set the new bits in the bit planes
  494.   or.w    d3,(a3)+
  495.   or.w    d4,(a4)+
  496.   or.w    d5,(a5)+
  497.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  498.   add.l   d0,d0
  499.   add.l   d0,a2
  500.   add.l   d0,a3
  501.   add.l   d0,a4
  502.   add.l   d0,a5
  503.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  504.   sub.w   d1,i(a1)               ;} /* did each row */
  505.   tst.w   i(a1)
  506.   bgt     Y0Loop4
  507.   movem.l (sp)+,SaveReg          ;better restore the registers
  508. #endasm
  509.  
  510.   RP = LP + CountX & 0xfff0;
  511.   RF = RP - 16;
  512.   CMod = CountX - (RP-LF);
  513.   Mod = Sx - ((RP-LF) >> 4);
  514.   TL++;
  515.   Width = (RP-LF) >> 4;
  516.   ColorPtr = ColorSave + LF - LP;
  517.  
  518. #asm
  519.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  520.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  521.   move.w  _CountY,i(a1)          ;i = CountY;
  522.   move.l  BitMap(a1),a0
  523.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  524.   asl.l   #1,d0                  ; and make it a 'word' offset
  525.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  526.   adda.l  d0,a2                  ; add in window top-left offset.
  527.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  528.   adda.l  d0,a3
  529.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  530.   adda.l  d0,a4
  531.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  532.   adda.l  d0,a5
  533.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  534.   move.l  #1,d1                  ;/* for each row */
  535. ;                                for (i = CountY; i; i--) {
  536. YLoop4                            ; /* for each column */
  537.   move.w  Width(a1),j(a1)        ;  for (j = Width; j; j--) {
  538. XLoop4                               ; /* pack a word for each bit plane */
  539.   move.w  #16,d7                 ;    for (k = 16; k; k--) {
  540. BLoop4
  541.   move.b  (a0)+,d0               ;      d0 = *(ColorPtr++);
  542.   asr.b   d1,d0                  ;      get low order bit from d0
  543.   addx.w  d2,d2                  ;      put it in bit plane 0 data
  544.   asr.b   d1,d0                  ;      same for bit plane 1
  545.   addx.w  d3,d3
  546.   asr.b   d1,d0                  ;      same for bit plane 2
  547.   addx.w  d4,d4
  548.   asr.b   d1,d0                  ;      same for bit plane 3
  549.   addx.w  d5,d5
  550.   sub.w   d1,d7                  ;      same for bit plane 5
  551.   bgt     BLoop4                 ;    } /* did each bit in bit plane word */
  552.   move.w  d2,(a2)+               ;    Save the packed data in bit planes
  553.   move.w  d3,(a3)+
  554.   move.w  d4,(a4)+
  555.   move.w  d5,(a5)+
  556.   sub.w   d1,j(a1)               ;  } /* did each word in a row */
  557.   tst.w   j(a1)
  558.   bgt     XLoop4
  559.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  560.   add.l   d0,d0
  561.   add.l   d0,a2
  562.   add.l   d0,a3
  563.   add.l   d0,a4
  564.   add.l   d0,a5
  565.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  566.   sub.w   d1,i(a1)               ;} /* did each row */
  567.   tst.w   i(a1)
  568.   bgt     YLoop4
  569.   movem.l (sp)+,SaveReg          ;better restore the registers
  570. #endasm
  571.  
  572.   TL += Width;
  573.   Width = LP + CountX - RP;
  574.   CMod = CountX - Width;
  575.   Mod = Sx - 1;
  576.   Mask = 0xffff >> Width;
  577.   ColorPtr = ColorSave + RP - LP;
  578.  
  579. #asm
  580.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  581.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  582.   move.w  _CountY,i(a1)
  583.   move.l  BitMap(a1),a0
  584.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  585.   asl.l   #1,d0                  ; and make it a 'word' offset
  586.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  587.   adda.l  d0,a2                  ; add in window top-left offset.
  588.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  589.   adda.l  d0,a3
  590.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  591.   adda.l  d0,a4
  592.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  593.   adda.l  d0,a5
  594.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  595.   move.l  #1,d1                  ;/* for each row */
  596. ;                                ;for (i = CountY; i; i--) {
  597. Y2Loop4                            ; /* for each pixel in column */
  598.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  599.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  600.   eor.w   d3,d3
  601.   eor.w   d4,d4
  602.   eor.w   d5,d5
  603. B2Loop4
  604.   move.b  (a0)+,d0                ;   d0 = *(ColorPtr++);
  605.   asr.b   d1,d0                   ;   get low order bit from d0
  606.   addx.w  d2,d2                   ;   put it in bit plane 0 data
  607.   asr.b   d1,d0                   ;   same for bit plane 1
  608.   addx.w  d3,d3
  609.   asr.b   d1,d0                   ;   same for bit plane 2
  610.   addx.w  d4,d4
  611.   asr.b   d1,d0                   ;   same for bit plane 3
  612.   addx.w  d5,d5
  613.   sub.w   d1,d7                   ;   same for bit plane 5
  614.   bgt     B2Loop4                 ; } /* did each bit in bit plane word */
  615.   move.w  Mask(a1),d0             ; Turn off all the new bits in planes
  616.   and.w   d0,(a2)
  617.   and.w   d0,(a3)
  618.   and.w   d0,(a4)
  619.   and.w   d0,(a5)
  620.   move.w  #16,d0
  621.   sub.w   Width(a1),d0
  622.   asl.w   d0,d2
  623.   asl.w   d0,d3
  624.   asl.w   d0,d4
  625.   asl.w   d0,d5
  626.   or.w    d2,(a2)+                ; Set the new bits in the bit planes
  627.   or.w    d3,(a3)+
  628.   or.w    d4,(a4)+
  629.   or.w    d5,(a5)+
  630.   move.l  Mod(a1),d0              ; Adjust plane pointers to start of next line
  631.   add.l   d0,d0
  632.   add.l   d0,a2
  633.   add.l   d0,a3
  634.   add.l   d0,a4
  635.   add.l   d0,a5
  636.   adda.l  CMod(a1),a0             ; Adjust color pointer to start of next line
  637.   sub.w   d1,i(a1)               ;} /* did each row */
  638.   tst.w   i(a1)
  639.   bgt     Y2Loop4
  640.   movem.l (sp)+,SaveReg          ;better restore the registers
  641. #endasm
  642. } /* ReColor 4 bit planes */
  643.  
  644.  
  645. /*
  646.  * Assembly code to recolor 5 bit planes
  647.  */
  648. ReColor5(ColorSave)
  649.   UBYTE *ColorSave;
  650. {
  651.   SHORT  Mask,Width;
  652.   LONG   Mod,CMod;
  653.   SHORT  LF,LP,RF,RP;
  654.   SHORT  i,j,k,l;
  655.   LONG   Sx,TL;
  656.   UBYTE  *ColorPtr;
  657.  
  658.   struct BitMap *BitMap = MandWind->RPort->BitMap;
  659.  
  660.   ColorPtr = ColorSave;
  661.   Sx = screen->Width >> 4;
  662.   LF = MandWind->LeftEdge + 17 & 0xfff0;
  663.   LP = MandWind->LeftEdge + LEFTMARG;
  664.   CMod = CountX - (LF-LP);
  665.   Mod = Sx - 1;
  666.   TL = Sx * (MandWind->TopEdge + TOPMARG) + (LP >> 4);
  667.   Width = LF-LP;
  668.   Mask = 0xffff << Width;
  669.  
  670. #asm
  671.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  672.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  673.   move.w  _CountY,i(a1)
  674.   move.l  BitMap(a1),a0
  675.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  676.   asl.l   #1,d0                  ; and make it a 'word' offset
  677.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  678.   adda.l  d0,a2                  ; add in window top-left offset.
  679.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  680.   adda.l  d0,a3
  681.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  682.   adda.l  d0,a4
  683.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  684.   adda.l  d0,a5
  685.   move.l  Plane4(a0),a6          ;Same for fifth bit plane.
  686.   adda.l  d0,a6
  687.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  688.   move.l  #1,d1                  ;/* for each row */
  689. ;                                ;for (i = CountY; i; i--) {
  690. Y0Loop5                            ; /* for each pixel in column */
  691.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  692.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  693.   eor.w   d3,d3
  694.   eor.w   d4,d4
  695.   eor.w   d5,d5
  696.   eor.w   d6,d6
  697. B0Loop5
  698.   move.b  (a0)+,d0               ;    d0 = *(ColorPtr++);
  699.   asr.b   d1,d0                  ;    get low order bit from d0
  700.   addx.w  d2,d2                  ;    put it in bit plane 0 data
  701.   asr.b   d1,d0                  ;    same for bit plane 1
  702.   addx.w  d3,d3
  703.   asr.b   d1,d0                  ;    same for bit plane 2
  704.   addx.w  d4,d4
  705.   asr.b   d1,d0                  ;    same for bit plane 3
  706.   addx.w  d5,d5
  707.   asr.b   d1,d0                  ;    same for bit plane 4
  708.   addx.w  d6,d6
  709.   sub.w   d1,d7                  ;    same for bit plane 5
  710.   bgt     B0Loop5                ;  } /* did each bit in bit plane word */
  711.   move.w  Mask(a1),d0            ;  Turn off all the new bits in planes
  712.   and.w   d0,(a2)
  713.   and.w   d0,(a3)
  714.   and.w   d0,(a4)
  715.   and.w   d0,(a5)
  716.   and.w   d0,(a6)
  717.   or.w    d2,(a2)+               ;  Set the new bits in the bit planes
  718.   or.w    d3,(a3)+
  719.   or.w    d4,(a4)+
  720.   or.w    d5,(a5)+
  721.   or.w    d6,(a6)+
  722.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  723.   add.l   d0,d0
  724.   add.l   d0,a2
  725.   add.l   d0,a3
  726.   add.l   d0,a4
  727.   add.l   d0,a5
  728.   add.l   d0,a6
  729.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  730.   sub.w   d1,i(a1)               ;} /* did each row */
  731.   tst.w   i(a1)
  732.   bgt     Y0Loop5
  733.   movem.l (sp)+,SaveReg          ;better restore the registers
  734. #endasm
  735.  
  736.   RP = LP + CountX & 0xfff0;
  737.   RF = RP - 16;
  738.   CMod = CountX - (RP-LF);
  739.   Mod = Sx - ((RP-LF) >> 4);
  740.   TL++;
  741.   Width = (RP-LF) >> 4;
  742.   ColorPtr = ColorSave + LF - LP;
  743.  
  744. #asm
  745.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  746.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  747.   move.w  _CountY,i(a1)          ;i = CountY;
  748.   move.l  BitMap(a1),a0
  749.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  750.   asl.l   #1,d0                  ; and make it a 'word' offset
  751.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  752.   adda.l  d0,a2                  ; add in window top-left offset.
  753.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  754.   adda.l  d0,a3
  755.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  756.   adda.l  d0,a4
  757.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  758.   adda.l  d0,a5
  759.   move.l  Plane4(a0),a6          ;Same for fifth bit plane.
  760.   adda.l  d0,a6
  761.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  762.   move.l  #1,d1                  ;/* for each row */
  763. ;                                ;for (i = CountY; i; i--) {
  764. YLoop5                            ; /* for each column */
  765.   move.w  Width(a1),j(a1)        ;  for (j = Width; j; j--) {
  766. XLoop5                               ; /* pack a word for each bit plane */
  767.   move.w  #16,d7                 ;    for (k = 16; k; k--) {
  768. BLoop5
  769.   move.b  (a0)+,d0               ;      d0 = *(ColorPtr++);
  770.   asr.b   d1,d0                  ;      get low order bit from d0
  771.   addx.w  d2,d2                  ;      put it in bit plane 0 data
  772.   asr.b   d1,d0                  ;      same for bit plane 1
  773.   addx.w  d3,d3
  774.   asr.b   d1,d0                  ;      same for bit plane 2
  775.   addx.w  d4,d4
  776.   asr.b   d1,d0                  ;      same for bit plane 3
  777.   addx.w  d5,d5
  778.   asr.b   d1,d0                  ;      same for bit plane 4
  779.   addx.w  d6,d6
  780.   sub.w   d1,d7                  ;      same for bit plane 5
  781.   bgt     BLoop5                 ;    } /* did each bit in bit plane word */
  782.   move.w  d2,(a2)+               ;    Save the packed data in bit planes
  783.   move.w  d3,(a3)+
  784.   move.w  d4,(a4)+
  785.   move.w  d5,(a5)+
  786.   move.w  d6,(a6)+
  787.   sub.w   d1,j(a1)               ;  } /* did each word in a row */
  788.   tst.w   j(a1)
  789.   bgt     XLoop5
  790.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  791.   add.l   d0,d0
  792.   add.l   d0,a2
  793.   add.l   d0,a3
  794.   add.l   d0,a4
  795.   add.l   d0,a5
  796.   add.l   d0,a6
  797.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  798.   sub.w   d1,i(a1)               ;} /* did each row */
  799.   tst.w   i(a1)
  800.   bgt     YLoop5
  801.   movem.l (sp)+,SaveReg          ;better restore the registers
  802. #endasm
  803.  
  804.   TL += Width;
  805.   Width = LP + CountX - RP;
  806.   CMod = CountX - Width;
  807.   Mod = Sx - 1;
  808.   Mask = 0xffff >> Width;
  809.   ColorPtr = ColorSave + RP - LP;
  810.  
  811. #asm
  812.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  813.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  814.   move.w  _CountY,i(a1)
  815.   move.l  BitMap(a1),a0
  816.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  817.   asl.l   #1,d0                  ; and make it a 'word' offset
  818.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  819.   adda.l  d0,a2                  ; add in window top-left offset.
  820.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  821.   adda.l  d0,a3
  822.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  823.   adda.l  d0,a4
  824.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  825.   adda.l  d0,a5
  826.   move.l  Plane4(a0),a6          ;Same for fifth bit plane.
  827.   adda.l  d0,a6
  828.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  829.   move.l  #1,d1                  ;/* for each row */
  830. ;                                ;for (i = CountY; i; i--) {
  831. Y2Loop5                          ;  ; /* for each pixel in column */
  832.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  833.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  834.   eor.w   d3,d3
  835.   eor.w   d4,d4
  836.   eor.w   d5,d5
  837.   eor.w   d6,d6
  838. B2Loop5
  839.   move.b  (a0)+,d0               ;    d0 = *(ColorPtr++);
  840.   asr.b   d1,d0                  ;    get low order bit from d0
  841.   addx.w  d2,d2                  ;    put it in bit plane 0 data
  842.   asr.b   d1,d0                  ;    same for bit plane 1
  843.   addx.w  d3,d3
  844.   asr.b   d1,d0                  ;    same for bit plane 2
  845.   addx.w  d4,d4
  846.   asr.b   d1,d0                  ;    same for bit plane 3
  847.   addx.w  d5,d5
  848.   asr.b   d1,d0                  ;    same for bit plane 4
  849.   addx.w  d6,d6
  850.   sub.w   d1,d7                  ;    same for bit plane 5
  851.   bgt     B2Loop5                ;  } /* did each bit in bit plane word */
  852.   move.w  Mask(a1),d0            ;  Turn off all the new bits in planes
  853.   and.w   d0,(a2)
  854.   and.w   d0,(a3)
  855.   and.w   d0,(a4)
  856.   and.w   d0,(a5)
  857.   and.w   d0,(a6)
  858.   move.w  #16,d0
  859.   sub.w   Width(a1),d0
  860.   asl.w   d0,d2
  861.   asl.w   d0,d3
  862.   asl.w   d0,d4
  863.   asl.w   d0,d5
  864.   asl.w   d0,d6
  865.   or.w    d2,(a2)+               ;  Set the new bits in the bit planes
  866.   or.w    d3,(a3)+
  867.   or.w    d4,(a4)+
  868.   or.w    d5,(a5)+
  869.   or.w    d6,(a6)+
  870.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  871.   add.l   d0,d0
  872.   add.l   d0,a2
  873.   add.l   d0,a3
  874.   add.l   d0,a4
  875.   add.l   d0,a5
  876.   add.l   d0,a6
  877.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  878.   sub.w   d1,i(a1)               ;} /* did each row */
  879.   tst.w   i(a1)
  880.   bgt     Y2Loop5
  881.   movem.l (sp)+,SaveReg          ;better restore the registers
  882. #endasm
  883. } /* ReColor 5 bit planes */
  884.  
  885. ReColorSlow() {
  886.   LONG i, j, x, y, xl, yl;
  887.   SHORT *CountPtr = CountBase;
  888.   UBYTE  T[1030];
  889.   UBYTE  OldColor;
  890.   UBYTE  NewColor;
  891.  
  892.   j = MaxCount;
  893.  
  894.   for (i = 0; i < NUMCONTS && j >= 0; i++)
  895.     for (; j >= ContourBase[i] && j >=0 ; )
  896.       T[j--] = ColorBase[i];
  897.   while (j >= 0) T[j--] = 0;
  898.  
  899.   OldColor = 0xff;
  900.   xl = CountX + LEFTMARG;
  901.   yl = CountY + TOPMARG;
  902.  
  903.   for (y = TOPMARG; y < yl; y++) {
  904.     for (x = LEFTMARG; x < xl; x++) {
  905.  
  906.       NewColor = T[ *CountPtr++ ];
  907.  
  908.       if ( NewColor != OldColor) {
  909.  
  910.         SetAPen( rp, NewColor );
  911.         OldColor = NewColor;
  912.       }
  913.       if (NewColor)
  914.         WritePixel(rp, x, y);
  915.     }
  916.   }
  917. } /* ReColorSlow */
  918.  
  919. /*
  920.  * Allocate all the gadgets and things for the contour window
  921.  */
  922. struct Gadget *MakeContours()
  923. {
  924.   struct Gadget *FirstGadget, *NextGadget, *OldGadget;
  925.  
  926.   extern struct Gadget *MakeBool(), *MakePot();
  927.   extern struct IntuiText *MakeIntui();
  928.  
  929.   USHORT i,x,y;
  930.   UBYTE c = 0;
  931.  
  932.   struct PropInfo *PropInfo;
  933.  
  934.   FirstGadget = OldGadget = MakePot(228, 26, 4, 32, CONTCEIL, 0);
  935.  
  936.   if (OldGadget == (struct Gadget *) NULL)
  937.     goto error;
  938.  
  939.   for (x = y = 0; x < 2; y += 10, x++) {
  940.  
  941.     NextGadget = MakeBool(234,y+14,6,6,1,CONTCNTL+x);
  942.  
  943.     if (NextGadget == (struct Gadget *) NULL)
  944.       goto error;
  945.  
  946.     switch (x) {
  947.       case 0:
  948.         NextGadget->GadgetText = MakeIntui("ReColor",10,-1,3,3,JAM1);
  949.         break;
  950.       case 1:
  951.         NextGadget->GadgetText = MakeIntui("Smooth",10,-1,3,3,JAM1);
  952.         break;
  953.     }
  954.     OldGadget->NextGadget = NextGadget;
  955.     OldGadget = NextGadget;
  956.   }
  957.  
  958.   for (x = y = 0; y < NumContours; x += 6, y++) {
  959.  
  960.     NextGadget = MakeBool(4+x, 12,4,4,Colors[y],CONTSEL+y);
  961.  
  962.     if (NextGadget == (struct Gadget *) NULL)
  963.       goto error;
  964.  
  965.     OldGadget->NextGadget = NextGadget;
  966.     OldGadget = SelGadget[y] = NextGadget;
  967.   }
  968.   NextGadget->GadgetText = MakeIntui("Set",6,-2,3,3,JAM1);
  969.  
  970.   for (x = y = 0; y < NumContours; x += 6, y++) {
  971.  
  972.     NextGadget = MakeBool(4+x, 18, 4, 4, 3, CONTUP + y);
  973.  
  974.     if (NextGadget == (struct Gadget *) NULL)
  975.       goto error;
  976.  
  977.     OldGadget->NextGadget = NextGadget;
  978.     OldGadget = NextGadget;
  979.   }
  980.   NextGadget->GadgetText = MakeIntui("+",6,-2,3,3,JAM1);
  981.  
  982.   /*
  983.    * Allocate the potentiometer gadgets for contour window
  984.    */
  985.   for (x = y = 0; y < NumContours; x += 6, y++) {
  986.  
  987.     NextGadget = MakePot(4+x, 24, 4, 32, CONTPOT+y, y);
  988.  
  989.     if (NextGadget == (struct Gadget *) NULL)
  990.       goto error;
  991.  
  992.     PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
  993.  
  994.     if (ContourBase[y] < Ceiling) {
  995.  
  996.       PropInfo->VertPot =
  997.  
  998.       (USHORT) ((((Ceiling - (ContourBase[y] + 1))<<16)/(Ceiling)) & 0xffff);
  999.  
  1000.     } else
  1001.       PropInfo->VertPot = 0;
  1002.  
  1003.     OldGadget->NextGadget = NextGadget;
  1004.     ContGadget[y] = NextGadget;
  1005.     OldGadget = NextGadget;
  1006.   }
  1007.   NextGadget->GadgetText = MakeIntui("Alt.",6,12,3,3,JAM1);
  1008.  
  1009.   /*
  1010.    * Allocate the push button gadgets for decrementing contours
  1011.    */
  1012.   for (x = y = 0; y < NumContours; x += 6, y++) {
  1013.  
  1014.     NextGadget = MakeBool(4+x, 58, 4, 4, 3, CONTDOWN + y);
  1015.  
  1016.     if (NextGadget == (struct Gadget *) NULL)
  1017.       goto error;
  1018.  
  1019.     if (y == NUMCONTS - 1) {
  1020.       NextGadget->GadgetText = MakeIntui("-",6,-2,3,3,JAM1);
  1021.     }
  1022.     OldGadget->NextGadget = NextGadget;
  1023.     OldGadget = NextGadget;
  1024.   }
  1025.   return( FirstGadget );
  1026.  
  1027. error:
  1028.   FreeGadgets(FirstGadget);
  1029.   return((struct Gadget *) NULL);
  1030.  
  1031. } /* MakeContours */
  1032.  
  1033. /*
  1034.  * Open the Contour window
  1035.  */
  1036. OpenContWind()
  1037. {
  1038.   struct Window *OpenMyWind();
  1039.   struct Gadget *gadgets;
  1040.  
  1041.   extern USHORT YScale;
  1042.  
  1043.   if (ContWind == (struct Window *) NULL) {
  1044.  
  1045.     gadgets = MakeContours();
  1046.  
  1047.     if (gadgets == (struct Gadget *) NULL) {
  1048.       DispErrMsg("Can't allocate contour gadget chain",0);
  1049.       return(0);
  1050.     }
  1051.  
  1052.     NewCont.TopEdge = 119 << YScale;
  1053.  
  1054.     ContWind = OpenMyWind(&NewCont, screen, gadgets, 320, 80, 320, 80);
  1055.  
  1056.     if (ContWind == (struct Window *) NULL) {
  1057.       DispErrMsg("Can't open Contour window",0);
  1058.       FreeGadgets(gadgets);
  1059.       return(0);
  1060.     }
  1061.     SetContTitle(0);
  1062.     DrawContBox(CurContour);
  1063.     ForceNormPointer();
  1064.   } else {
  1065.     WindowToFront( ContWind );
  1066.   }
  1067.   return(1);
  1068. } /* OpenContWind */
  1069.  
  1070. /*
  1071.  * Close the Mand window
  1072.  */
  1073. CloseContWind()
  1074. {
  1075.   if (ContWind != (struct Window *) NULL) {
  1076.     CloseMyWind(ContWind,NewCont.FirstGadget);
  1077.     ContWind = (struct Window *) NULL;
  1078.   }
  1079. } /* ClosePalWind */
  1080.  
  1081. /*
  1082.  * ReDisplay a given contour potentiometer gadget
  1083.  */
  1084. ReString(PotNum)
  1085.   SHORT PotNum;
  1086. {
  1087.   SHORT i;
  1088.   USHORT VertPot;
  1089.  
  1090.   if (ContourBase[PotNum] < Ceiling)
  1091.     VertPot = (USHORT) ((((Ceiling - (ContourBase[PotNum]+1))<<16)/(Ceiling)) & 0xffff);
  1092.   else
  1093.     VertPot = (USHORT) 0;
  1094.   NewModifyProp(ContGadget[PotNum], ContWind, NULL, FREEVERT | PROPBORDERLESS,
  1095.                 0L, VertPot, 0L, 0L, 1L);
  1096. } /* ReString */
  1097.  
  1098. /*
  1099.  * ReDisplay all the contour potentiometer gadgets
  1100.  */
  1101. ModAll()
  1102. {
  1103.   SHORT i;
  1104.   USHORT VertPot;
  1105.   struct Gadget *PropGad = (struct Gadget *) ContGadget[0];
  1106.  
  1107.   for (i = 0; i < NUMCONTS; i++) {
  1108.     if (ContourBase[i] < Ceiling) {
  1109.       VertPot = (USHORT) ((((Ceiling - (ContourBase[i] + 1))<<16)/(Ceiling)) & 0xffff);
  1110.     } else
  1111.       VertPot = (USHORT) 0;
  1112.     NewModifyProp(PropGad,ContWind,NULL,FREEVERT|PROPBORDERLESS,0L,VertPot,0L,0L,1L);
  1113.     PropGad = PropGad->NextGadget;
  1114.   }
  1115. } /* ModAll */
  1116.